﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Text.RegularExpressions;
using System.IO;
using System.Xml.Linq;

namespace WebCrawl
{
    public partial class Form1 : Form
    {
        int count = 0; // 记录已爬取的电话号码的数量
        Queue<string> urls = new Queue<string>();         // 存储待爬取的URL的栈
        HashSet<string> visitedUrls = new HashSet<string>(); // 存储已爬取的URL

        public Form1()
        {
            InitializeComponent();
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            // 获取用户输入的关键字
            string keyword = textBox1.Text;
            // 使用bing搜索引擎进行搜索
            // keyword转为url中的字符编码
            string encodedKeyword = Uri.EscapeDataString(keyword);
            string searchUrl = $"https://cn.bing.com/search?q={encodedKeyword}&cvid=1df8d29ba2484974bc15312da45d5033&gs_lcrp=EgRlZGdlKgYIABBFGDkyBggAEEUYOTIGCAEQABhAMgYIAhAAGEAyBggDEAAYQDIGCAQQABhAMgYIBRAAGEAyBggGEEUYPTIGCAcQRRg9MgYICBBFGD3SAQgyNDY3ajBqMagCALACAA";
            urls.Enqueue(searchUrl);
            await CrawlAsync();
        }

        private async Task CrawlAsync()
        {
            while (urls.Count > 0 && count <= 100)
            {
                // 从栈中取出待爬取的URL
                string url = urls.Dequeue();

                // 检查URL是否已经爬取过
                if (visitedUrls.Contains(url))
                {
                    continue;
                }

                try
                {
                    // 使用WebRequest类进行爬取
                    WebRequest request = WebRequest.Create(url);
                    request.Method = "GET";
                    // 获取请求结果
                    using (WebResponse response = await request.GetResponseAsync())
                    {
                        // 在ListBox1中追加当前URL
                        Invoke(new Action(() => listBox1.Items.Add(url)));

                        // 将当前URL标记为已爬取
                        visitedUrls.Add(url);

                        // 解析结果中的HTML代码，提取出所有的超链接
                        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                        {
                            string html = await reader.ReadToEndAsync();
                            Regex regex = new Regex("https?://(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}(?::\\d{2,5})?(?:/[^\\s]*)?(?:\\?[^\\s]*)?");
                            foreach (Match match in regex.Matches(html))
                            {
                                string link = match.Value;
                                // 添加到待爬取的队列
                                if (!visitedUrls.Contains(link))
                                {
                                    urls.Enqueue(link);
                                }
                            }

                            // 解析结果中的电话号码
                            Regex phoneRegex = new Regex("\\d{3}-\\d{8}|\\d{4}-\\d{7}|^1(3[0-9]|4[57]|5[0-35-9]|7[0678]|8[0-9])\\d{8}$");
                            foreach (Match match in phoneRegex.Matches(html))
                            {
                                string phone = match.Value;
                                count++;
                                Invoke(new Action(() => listBox2.Items.Add(count.ToString().PadLeft(5) + " : " + phone + " : " + url)));
                            }
                        }
                    }
                }
                catch (UriFormatException)
                {
                    // 如果URL格式不正确，跳过当前URL
                }
                catch (WebException ex)
                {
                    // 请求失败，跳过当前URL
                }

                // 进行下一次爬取
                await Task.Delay(0);
            }
        }
    }
}